﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace RegExStudy
{
    /// <summary>
    /// 前后查找
    /// </summary>
    public class Chapter9
    {
        // 使用表达式标记要匹配的文本的位置

        /// <summary>
        /// 前后查找
        /// </summary>
        public void Check1()
        {
            // 举例不使用前后查找前的不足
            // 查找在 <title></title> 内的内容
            string str = "<body><title>前后查找</title>   </body>";

            var arry = Regex.Matches(str, @"<[Tt][Ii][Tt][Ll][Ee]>.*</[Tt][Ii][Tt][Ll][Ee]>");
            Console.WriteLine(string.Format("Check1 查询 文本 \n {0} \n匹配字符 {1} ", str, @"<[Tt][Ii][Tt][Ll][Ee] >.*</[Tt][Ii][Tt][Ll][Ee]>"));
            // 返回的是 <title>前后查找</title>   但是需要的是  前后查找 这个里面的内容
            // 虽然可以用第八章的内容  把前后变成子表达式，然后用 $ 来获取，但是一开始就没必要查找到没用的数据 <title></title>
            Console.WriteLine("匹配的数量 ： " + arry.Count);
            foreach (var item in arry)
            {
                Console.WriteLine(string.Format("分别为 {0} ", item.ToString()));
            }
            Console.WriteLine();
        }

        /// <summary>
        /// 向前查找   ?=   的使用(需要匹配的字符在=后面)
        /// </summary>
        public void Check2()
        {
            //  ?=xxx  指从前往后查找，直到xxx匹配上后停止，xxx不在输出的内容里

            // 这里查找 url的开头内容
            string str = "http://www.bilibili.com \n https://alibaba.com \n ftp://ftp.fora.com";

            var arry = Regex.Matches(str, @".+(?=:)");
            Console.WriteLine(string.Format("Check1 查询 文本 \n {0} \n匹配字符 {1} ", str, @".+(?=:)"));
            Console.WriteLine("匹配的数量 ： " + arry.Count);

            foreach (var item in arry)
            {
                Console.WriteLine(string.Format("分别为 {0} ", item.ToString()));
            }
            Console.WriteLine();
        }

        /// <summary>
        /// 向后查找
        /// </summary>
        public void Check3()
        {
            // ?<=   它必须用在一个子表达式里，而且后面跟要匹配的文本

            // 假设只提取价格部分 ￥后的数字部分
            string str = "苹果：￥10.78  香蕉：￥4.8  雪梨：￥13.62  橙子：8.88  ";

            var arry = Regex.Matches(str, @"(?<=\￥)[0-9.]+");
            Console.WriteLine(string.Format("Check3 查询 文本 \n {0} \n匹配字符 {1} ", str, @"(?<=\￥)[0-9.]+"));
            Console.WriteLine("匹配的数量 ： " + arry.Count);
            foreach (var item in arry)
            {
                Console.WriteLine(string.Format("分别为 {0} ", item.ToString()));
            }
            Console.WriteLine();
        }

        /// <summary>
        /// 把向前查找和向后查找结合起来
        /// </summary>
        public void Check4()
        {
            //这里解决 Check1 中无法正确匹配的问题
            string str = "<body><title>前后查找</title>   </body>";

            var arry = Regex.Matches(str, @"(?<=<[Tt][Ii][Tt][Ll][Ee]>).*(?=</[Tt][Ii][Tt][Ll][Ee]>)");
            Console.WriteLine(string.Format("Check4 查询 文本 \n {0} \n匹配字符 {1} ", str, @"(?<=<[Tt][Ii][Tt][Ll][Ee]>).*(?=</[Tt][Ii][Tt][Ll][Ee]>)"));
            Console.WriteLine("匹配的数量 ： " + arry.Count);
            foreach (var item in arry)
            {
                Console.WriteLine(string.Format("分别为 {0} ", item.ToString()));
            }
            Console.WriteLine();
        }

        /// <summary>
        /// 对前后查找取非
        /// </summary>
        public void Check5()
        {
            // 与前面学习的 ^ 类似   
            // (?=)  正向前查找   (?!) 负向前查找
            // (?<=) 正向后查找    (?<!) 负向后查找

            string str = "I paid $30 for 100 apples,50 oranges,and 60 pears.I saved $5 on this order.";

            //1 从文本中获取价格  即取跟在 $ 后的数字
            var arry = Regex.Matches(str, @"(?<=\$)\d+");
            Console.WriteLine(string.Format("Check5 查询 文本 价格 \n {0} \n匹配字符 {1} ", str, @"(?<=\$)\d+"));
            Console.WriteLine("匹配的数量 ： " + arry.Count);
            foreach (var item in arry)
            {
                Console.WriteLine(string.Format("分别为 {0} ", item.ToString()));
            }
            Console.WriteLine();

            //2 查找数量
            arry = Regex.Matches(str, @"(?<!\$)\d+");
            Console.WriteLine(string.Format("Check5 查询 文本 数量 \n {0} \n匹配字符 {1} ", str, @"(?<!\$)\d+"));
            Console.WriteLine("匹配的数量 ： " + arry.Count);
            foreach (var item in arry)
            {
                Console.WriteLine(string.Format("分别为 {0} ", item.ToString()));
            }
            Console.WriteLine();
            // 上面这里看似没问题，但是输出是不对的，因为这里需要有边界，数量前后是空格，不带其他东西的

            // 需要在前后添加 \b 的边界限制
            arry = Regex.Matches(str, @"\b(?<!\$)\d+\b");
            Console.WriteLine(string.Format("Check5 查询 文本 数量 \n {0} \n匹配字符 {1} ", str, @"\b(?<!\$)\d+\b"));
            Console.WriteLine("匹配的数量 ： " + arry.Count);
            foreach (var item in arry)
            {
                Console.WriteLine(string.Format("分别为 {0} ", item.ToString()));
            }
            Console.WriteLine();
        }
    }
}
